package com.coocaa.x.demo.servlets;

import com.coocaa.x.framework.data.JObject;
import com.coocaa.x.service.litewebserver.webserver.LiteWebHttpd;
import com.coocaa.x.service.litewebserver.webserver.NanoHTTPD;
import com.coocaa.x.service.litewebserver.webserver.servlet.Servlet;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by lu on 15-9-12.
 */
public class SDeviceServlet extends Servlet {

    public static class SDevice extends JObject {
        public String sn;
        public String label;
        public String vendor, id;
        public ServletName servletName;

        private static final String SN_FORMAT = "%s-%s-%s";

        public final String thisSDeviceSN() {
            return String.format(SN_FORMAT, vendor, id, sn);
        }
    }

    private static abstract class DeviceSearchRunnable implements Runnable {
        private static Map<String, SDevice> devices = null;

        public static void setSDevicesMap(Map<String, SDevice> devices) {
            DeviceSearchRunnable.devices = devices;
        }

        protected final boolean addSDevice(SDevice d) {
            synchronized (DeviceSearchRunnable.devices) {
                if (DeviceSearchRunnable.devices.containsKey(d.sn))
                    return false;
                DeviceSearchRunnable.devices.put(d.sn, d);
                return true;
            }
        }

        public abstract String getName();
    }

    private ServletInfo info = null;

    private Map<String, SDevice> devices = new HashMap<String, SDevice>();

    @Override
    protected void onCreate() {
        getSessionHandler().addHandler("/search", search);
        getSessionHandler().addHandler("/mydevice", mydevice);
    }

    @Override
    protected void onDestroy() {

    }

    @Override
    protected NanoHTTPD.Response onServe(NanoHTTPD.IHTTPSession session) {
        return getSessionHandler().handle(session);
    }

    @Override
    public synchronized ServletInfo getServletInfo() {
        if (info == null) {
            info = new ServletInfo();
            info.vendorName = "superx";
            info.servletName = "sdevice";
            info.versionCode = 1;
            info.versionName = "1.0.0";
        }
        return info;
    }

    @Override
    protected InputStream getResource(String uri) {
        return null;
    }

    private LiteWebHttpd.ServletHandler search = new LiteWebHttpd.ServletHandler() {
        private DeviceSearchRunnable demoDevice = new DeviceSearchRunnable() {
            private SDevice player = null;

            @Override
            public String getName() {
                return "Search DemoDevice";
            }

            private void init() {
                if (player == null) {
                    player = new SDevice();
                    player.vendor = "superx";
                    player.id = "player";
                    player.label = "Super Player";
                    player.sn = "10000001";
                    player.servletName = new ServletName("superx", "player");
                }
            }

            @Override
            public void run() {
                init();
                addSDevice(player);
            }
        };


        private ThreadGroup searchThreadGroup = new ThreadGroup("Device Search");
        private final DeviceSearchRunnable[] rs = {demoDevice};

        @Override
        public synchronized NanoHTTPD.Response serve(NanoHTTPD.IHTTPSession session) {
            if (searchThreadGroup.activeCount() == 0) {
                synchronized (devices) {
                    devices.clear();
                    DeviceSearchRunnable.setSDevicesMap(devices);
                }
                for (DeviceSearchRunnable r : rs) {
                    Thread t = new Thread(searchThreadGroup, r, r.getName());
                    t.start();
                }
            }
            return newResponseMessage(null);
        }
    };

    private LiteWebHttpd.ServletHandler mydevice = new LiteWebHttpd.ServletHandler() {
        class MyDeviceResponseMessage extends ResponseMessage {
            public int count;
            public List<SDevice> devices;
        }

        @Override
        public NanoHTTPD.Response serve(NanoHTTPD.IHTTPSession session) {
            NanoHTTPD.Response r;
            synchronized (devices) {
                Collection<SDevice> ds = devices.values();
                MyDeviceResponseMessage msg = new MyDeviceResponseMessage();
                msg.count = ds.size();
                msg.devices = new ArrayList<SDevice>();
                for (SDevice d : ds)
                    msg.devices.add(d);
                r = newResponseMessage(msg);
            }
            return r;
        }
    };
}
